#define _CRT_SECURE_NO_WARNINGS 1
#include "Link.h"

LinkNode* linkCreate(LinkData val) {
	LinkNode* newnode = (LinkNode*)calloc(1, sizeof(LinkNode));
	if (newnode == NULL) {
		perror("linkCreate->calloc");
		exit(-1);
	}
	newnode->data = val;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}

LinkNode* linkInit() {
	LinkNode* head = linkCreate(-1);
	head->next = head;
	head->prev = head;
	return head;
}

void linkPrint(LinkNode* phead) {
	assert(phead);
	LinkNode* cur = phead->next;
	printf("head<->");
	while (cur != phead) {
		printf("%d<->", cur->data);
		cur = cur->next;
	}
	printf("head");
}

LinkNode* linkFind(LinkNode* phead, LinkData val) {
	assert(phead);
	LinkNode* cur = phead->next;
	while (cur != phead) {
		if (val == cur->data) {
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void linkPushBack(LinkNode* phead, LinkData num) {
	assert(phead);
	LinkNode* newnode = linkCreate(num);
	LinkNode* tail = phead->prev;
	
	newnode->prev = tail;
	newnode->next = phead;
	tail->next = newnode;
	phead->prev = newnode;
}

void linkPopBack(LinkNode* phead) {
	assert(phead);
	assert(phead != phead->next);
	LinkNode* tail = phead->prev;

	phead->prev = tail->prev;
	tail->prev->next = phead;

	free(tail);
}

void linkPushFront(LinkNode* phead, LinkData num) {
	assert(phead);
	LinkNode* newnode = linkCreate(num);
	
	newnode->prev = phead;
	newnode->next = phead->next;
	phead->next->prev = newnode;
	phead->next = newnode;
}

void linkPopFront(LinkNode* phead) {
	assert(phead);
	assert(phead != phead->next);
	LinkNode* front = phead->next;

	phead->next = front->next;
	front->next->prev = phead;
}

void linkInsert(LinkNode* phead, LinkData val, LinkData num) {
	assert(phead);
	LinkNode* pos = linkFind(phead, val);
	assert(pos);
	LinkNode* newnode = linkCreate(num);
	pos->prev->next = newnode;
	newnode->next = pos;
	newnode->prev = pos->prev;
	pos->prev = newnode;
}

void linkErase(LinkNode* phead, LinkData val) {
	assert(phead);
	LinkNode* pos = linkFind(phead, val);
	assert(pos);

	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;

	free(pos);
}

void linkDestory(LinkNode* phead) {
	assert(phead);
	LinkNode* cur = phead->next;
	LinkNode* next = NULL;
	while (cur != phead) {
		next = cur->next;
		free(cur);
		cur = next;
	}
}